using KinonekoSoftware.CodariaDB.Documents.Templates;
using System.Collections;

namespace KinonekoSoftware.Studio.Pages.Theories
{
    public sealed class WVCTemplateDefinitionGeneratorViewModel : SelectionDialog<DataPartTypeSelector>
    {
        private readonly HashSet<DataPartTypeSelector> _Selected;
        private          DataPartTypes                 _selectedDataPartTypes;
        private readonly HashSet<DataPartType>          _set;



        public WVCTemplateDefinitionGeneratorViewModel()
        {
            _set                             = new HashSet<DataPartType>();
            _Selected                        = new HashSet<DataPartTypeSelector>();
            CollectionOfDataPartTypeSelector = new ObservableCollection<DataPartTypeSelector>();
            IsMultipleSelection              = true;
        }
        
        
        public WVCTemplateDefinitionGeneratorViewModel(IEnumerable<DataPartType> types)
        {
           _set = types.ToHashSet();
            CollectionOfDataPartTypeSelector = new ObservableCollection<DataPartTypeSelector>();
            _Selected                        = new HashSet<DataPartTypeSelector>();
            IsMultipleSelection              = true;
        }

        public static async Task<Result<IList<DataPartTypeSelector>>> Select()
        {
            return await Dialog((ISelectionDialog<DataPartTypeSelector>)new WVCTemplateDefinitionGeneratorViewModel());
        }
        
        public static async Task<Result<IList<DataPartTypeSelector>>> Select(IEnumerable<DataPartType> types)
        {
            return await Dialog((ISelectionDialog<DataPartTypeSelector>)new WVCTemplateDefinitionGeneratorViewModel(types));
        }

        protected override void OnStart()
        {
            foreach (var type in DataPartTypeHelper.Types)
            {
                foreach (var selector in type.Items)
                {
                    selector.ValueChangedHandler = OnSelected;
                }
            }
        }

        protected override void OnStop()
        {
            foreach (var type in DataPartTypeHelper.Types)
            {
                foreach (var selector in type.Items)
                {
                    selector.ClearSelection();
                    selector.ValueChangedHandler = null;
                }
            }
        }

        private void OnSelected(DataPartTypeSelector target, bool value, string mutex)
        {
            if (!string.IsNullOrEmpty(target.Mutex) && DataPartTypeHelper.Mutex.TryGetValue(target.Mutex, out var container))
            {
                //
                // 清除所有已选择的，且不是当前选项的按钮
                container.ForEach(x =>
                {
                    if (x.IsSelected && !ReferenceEquals(target, x))
                    {
                        x.ClearSelection();
                        _Selected.Remove(x);
                    }
                });
            }

            if (_Selected.Count >= 16)
            {
                target.ClearSelection();
                return;
            }

            if (value)
            {
                _Selected.Add(target);
            }
            else
            {
                _Selected.Remove(target);
            }
        }

        protected override void CreateValidationRules(ICollection<DialogRule> rules)
        {

        }

        protected override IList<DataPartTypeSelector> OnFinish(bool editing)
        {
            return _Selected.ToList();
        }

        /// <summary>
        /// 获取或设置 <see cref="SelectedDataPartTypes"/> 属性。
        /// </summary>
        public DataPartTypes SelectedDataPartTypes
        {
            get => _selectedDataPartTypes;
            set
            {
                SetValue(ref _selectedDataPartTypes, value);
                CollectionOfDataPartTypeSelector.AddMany(value.Items.Where(x => !_set.Contains(x.Type)), true);
            }
        }

        public ReadOnlyObservableCollection<DataPartTypes> CollectionOfDataPartTypes        => DataPartTypeHelper.Types;
        public ObservableCollection<DataPartTypeSelector>  CollectionOfDataPartTypeSelector { get; }
    }
}